package main

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

type DbConfig struct {
	Ip       string `mapstructure:"ip" ini:"ip" yaml:"ip"`
	User     string `mapstructure:"user" ini:"user" yaml:"user"`
	Password string `mapstructure:"password" ini:"password" yaml:"password"`
}

type GlobalConfig struct {
	config DbConfig `mapstructure:"db" ini:"db" yaml:"db"`
}

func main() {
	v := viper.New()
	globalConfig := GlobalConfig{}
	// 设置配置文件
	//v.SetConfigFile("13_viper/config/config.ini")
	v.SetConfigFile("13_viper/config/conf.yaml")
	// 设置配置文件目录，之后的文件都会直接在目录中查找
	//v.AddConfigPath("13_viper/config")
	// 读配置
	err := v.ReadInConfig() // 查找并读取配置文件
	if err != nil {         // 处理读取配置文件的错误
		fmt.Println()
		panic(fmt.Errorf("Fatal error config file: %s \n", err))
	}
	// 读配置项

	// 反序列化失败，不知道为什么
	err = v.Unmarshal(&globalConfig)
	if err != nil {
		panic(err)
	}
	fmt.Printf("struct:%+v\n", globalConfig)
	all := v.AllSettings()
	fmt.Printf("all settings: %+v\n", all)
	ip := v.GetString("db.ip")
	user := v.GetString("db.user")
	fmt.Printf("ip=%s,user=%s\n", ip, user)

	// 设置
	v.Set("db.password", "12345")
	// 写入文件
	err = v.WriteConfig()
	if err != nil {
		panic(err)
	}

	// 监听配置文件的变化
	v.WatchConfig()
	v.OnConfigChange(func(in fsnotify.Event) {
		fmt.Println("change event：", in.String())
		// 解析到结构体
		err := v.Unmarshal(&globalConfig)
		if err != nil {
			panic(err)
		}
		fmt.Printf("config change event:%+v\n", globalConfig)
	})

	v.Set("db.password", "54321")
	err = v.WriteConfig()
	if err != nil {
		panic(err)
	}

}
